import { defaultHttpServerOption } from './default';
import axios, { AxiosInstance } from 'axios';
import { IHttpserverOption, IHttpServer } from './interface';
import { IId } from '../interfaces';

class HttpServer implements IHttpServer {
  private server: AxiosInstance
  constructor(prefix:string, option?:IHttpserverOption) {
    this.server = axios.create({
      baseURL: prefix,
    })
    if (!option) {
      option = {}
    }
    option.successRequestInterceptor = option.successRequestInterceptor || defaultHttpServerOption.successRequestInterceptor
    option.failtRequestInterceptor = option.failtRequestInterceptor || defaultHttpServerOption.failtRequestInterceptor
    option.successResponseInterceptor = option.successResponseInterceptor || defaultHttpServerOption.successResponseInterceptor
    option.FailResponseInterceptor = option.FailResponseInterceptor || defaultHttpServerOption.FailResponseInterceptor
    this.server.interceptors.request.use(option.successRequestInterceptor, option.failtRequestInterceptor)
    this.server.interceptors.response.use(option.successResponseInterceptor, option.FailResponseInterceptor)
  }

  public async get<T>(url:string, query?:object):Promise<T> {
    return this.server.get(url, query) as any;
  }
  public async post<T>(url:string, data?:any):Promise<T> {
    return this.server.post(url, data) as any;
  }

  public async put<T>(url:string, data?:any):Promise<T> {
    return this.server.put(url, data) as any;
  }

  public async delete<T>(url:string, data?:any):Promise<T> {
    return this.server.delete(url, data) as any ;
  }

  public getResource<T> (resourceName:string, resourceId:string, query?:object):Promise<T> {
    return this.get(`/${resourceName}/${resourceId}`, query)
  }
  public getResources<T> (resourceName:string, query?:object):Promise<T> {
    return this.get(`/${resourceName}`, query)
  }
  public createResource<T> (resourceName:string, resource:IId):Promise<T> {
    return this.post(`/${resourceName}`, resource)
  }
  public replaceResource<T> (resourceName:string, resource:IId) :Promise<T>{
    return this.put(`//${resourceName}/${resource.id}`, resource)
  }
  public deleteResource<T> (resourceName:string, resource:IId):Promise<T> {
    return this.delete(`/${resourceName}/${resource.id}`)
  }

}

export default HttpServer
